home *** CD-ROM | disk | FTP | other *** search
- /*
- Crop a PICT resource
- ...allowing one to crop a PICS file or a series of PICT files
- */
-
- #include <QDOffscreen.h>
- #include "CropPICTs.h"
- #include "PICS_Types.h"
- #include "SavePicture.h"
- #include "assert_mac.h"
- #include "QDUtils.h" // For CenterRect
- #include "FileRegistry.h"
-
- // ---------------------------------------------------------------------------
-
- /*
- The <picBuffer> is assumed to be at least the same or larger
- dimensions than that of <inputPic>. If you pass the address of
- an empty PicHandle to <croppedPic>, CropPICT will record the
- cropped <inputPic> as a picture to <croppedPic>. If you pass NULL
- instead, no picture will be saved.
-
- <destBuffer> may be the same as <picBuffer>
- <srcCropRect> may be the same as <destCropRect>
- */
-
- Boolean CropPICT(
- const PicHandle inputPic,
- const GraphicsBufferPtr picBuffer,
- const GraphicsBufferPtr destBuffer,
- const Rect *srcCropRect,
- const Rect *destCropRect,
- PicHandle *croppedPic) {
-
- GWorldPtr saveWorld;
- GDHandle saveDev;
- Rect picRect;
- Boolean result;
-
- ASSERT(inputPic != NULL);
- ASSERT(picBuffer != NULL);
- ASSERT(destBuffer != NULL);
- ASSERT(srcCropRect != NULL);
- ASSERT(destCropRect != NULL);
-
- GetGWorld(&saveWorld, &saveDev);
- SetGraphicsBuffer(picBuffer);
- picRect = (**inputPic).picFrame;
- FlushRectTopLeft(&picRect);
- DrawPicture(inputPic, &picRect);
-
- result = CapturePICT(picBuffer, destBuffer, srcCropRect, destCropRect, croppedPic);
-
- SetGWorld(saveWorld, saveDev);
- return(result);
- } // END CropPICT
-
- // ---------------------------------------------------------------------------
-
- Boolean CapturePICT(
- const GraphicsBufferPtr srcBuffer,
- const GraphicsBufferPtr destBuffer,
- const Rect *srcRect,
- const Rect *destRect,
- PicHandle *croppedPic) {
-
- GWorldPtr saveWorld;
- GDHandle saveDev;
- Rect clipRect;
- RgnHandle saveClip;
-
- ASSERT(srcBuffer != NULL);
- ASSERT(destBuffer != NULL);
- ASSERT(srcRect != NULL);
- ASSERT(destRect != NULL);
-
- GetGWorld(&saveWorld, &saveDev);
- SetGraphicsBuffer(destBuffer);
-
- if (croppedPic != NULL) {
- saveClip = NewRgn();
- ASSERT(saveClip != NULL);
- GetClip(saveClip);
- GetGraphicsBufferBounds(destBuffer, (CP_Rect*)&clipRect);
- // It's in global coords so we have to adjust it
- FlushRectTopLeft(&clipRect);
- ClipRect(&clipRect);
-
- *croppedPic = OpenPicture(destRect);
- ASSERT(*croppedPic != NULL);
- }
-
- CopyGraphicsBuffer(srcBuffer, destBuffer,
- (CP_Rect*)srcRect, (CP_Rect*)destRect);
-
- if (croppedPic != NULL) {
- ClosePicture();
- ASSERT(*croppedPic != NULL);
-
- SetClip(saveClip);
- DisposeRgn(saveClip);
- SetGWorld(saveWorld, saveDev);
- }
-
- return(true);
- } // END CapturePICT
-
- // ---------------------------------------------------------------------------
-
- /*
- This routine assumes you already have picked the input <picsFile> and
- created the output <outputFile>. It also assumes that you have set the
- depth of monitor <outputDevice> appropriately, prior to calling the routine.
- (CropPICSFile uses the depth of <outputDevice> to determine the depth
- of the output PICS frames).
-
- Technically, the order of the frames in a PICS file should be by
- resource ID. However, a few programs just assume it's by the order
- of the resources in the resource file. BIG MISTAKE! If you should
- use ResEdit to cut and paste in the PICS file, the order will be
- changed (but the resource id shouldn't be - and you can always change
- that, unlike the order). So we'll be flexible by adding the
- <traversePICSByID> parameter.
- */
-
- OSErr CropPICSFile(
- Boolean traversePICSByID,
- const Rect *cropArea,
- const GDHandle outputDevice,
- const FSSpec *picsFile,
- const FSSpec *outputFile) {
-
- short inputFileRef;
- short outputFileRef;
- short numPicts;
-
- ASSERT(cropArea != NULL);
- ASSERT(outputDevice != NULL);
- ASSERT(picsFile != NULL);
- ASSERT(outputFile != NULL);
-
- inputFileRef = FSpOpenResFile(picsFile, fsRdWrPerm);
- if (inputFileRef == -1 || !RegisterFile(inputFileRef)) {
- return(ResError());
- }
-
- outputFileRef = FSpOpenResFile(outputFile, fsRdWrPerm);
- if (outputFileRef == -1 || !RegisterFile(outputFileRef)) {
- return(ResError());
- }
-
- UseResFile(inputFileRef);
- numPicts = Count1Resources(kPICSRsrcType);
- if (numPicts < 1) {
- (void)UnregisterFile(inputFileRef);
- (void)UnregisterFile(outputFileRef);
- CloseResFile(inputFileRef);
- CloseResFile(outputFileRef);
- return(-1);
- }
-
- short i;
- short resID;
- PicHandle inputPict;
- PicHandle outputPict;
- Rect cropBufferRect;
- Rect outputDeviceRect;
- Rect outputCropRect;
- GBErr gbErr;
- GWorldPtr saveWorld;
- GDHandle saveDev;
- GraphicsBufferPtr cropBuffer;
-
- GetGWorld(&saveWorld, &saveDev);
-
- // Pre-fetch one PICT rsrc to get it's dimensions
- inputPict = (PicHandle)Get1IndResource(kPICSRsrcType, 1);
- cropBufferRect = (**inputPict).picFrame;
-
- // Allocate offscreen graphics buffer
- outputDeviceRect = (**outputDevice).gdRect;
- // Place cropBuffer onto the device we're to "work on" (make global coords)
- CenterRect(&cropBufferRect, &outputDeviceRect);
- gbErr = NewGraphicsBuffer(&cropBuffer, 0, (CP_Rect*)&cropBufferRect,
- kGBOptimalFlag, 0);
- // Restore to local coords
- FlushRectTopLeft(&cropBufferRect);
-
- outputCropRect = *cropArea;
- FlushRectTopLeft(&outputCropRect);
-
- // For PICS files, we'll assume the rsrc id ALWAYS starts at 128.
- for (i = 1, resID = kPICSRsrcStartID; i <= numPicts; i++, resID++) {
- if (traversePICSByID)
- inputPict = (PicHandle)Get1Resource(kPICSRsrcType, resID);
- else
- inputPict = (PicHandle)Get1IndResource(kPICSRsrcType, i);
-
- if (inputPict == NULL) {
- (void)UnregisterFile(inputFileRef);
- (void)UnregisterFile(outputFileRef);
- CloseResFile(inputFileRef);
- CloseResFile(outputFileRef);
- DisposeGraphicsBuffer(cropBuffer);
- return(-2);
- }
-
- // Crop it!
- (void)CropPICT(inputPict, cropBuffer, cropBuffer,
- cropArea, &outputCropRect, &outputPict);
- ReleaseResource((Handle)inputPict);
-
- if (!SavePictureResource(outputPict, outputFileRef, resID, NULL)) {
- (void)UnregisterFile(inputFileRef);
- (void)UnregisterFile(outputFileRef);
- CloseResFile(inputFileRef);
- CloseResFile(outputFileRef);
- DisposeGraphicsBuffer(cropBuffer);
- return(-3);
- }
-
- // Dispose & release memory
- KillPicture(outputPict);
- }
-
- SetGWorld(saveWorld, saveDev);
- (void)UnregisterFile(inputFileRef);
- (void)UnregisterFile(outputFileRef);
- CloseResFile(inputFileRef);
- CloseResFile(outputFileRef);
- DisposeGraphicsBuffer(cropBuffer);
- return(noErr);
- } // END CropPICSFile
-